#include "SMPPDecoder.hpp"

#ifndef ntohs
#define ntohs(A) ((((unsigned short)(A) &0xff00) >> 8) | \
	(((unsigned short)(A) &0x00ff) << 8))
#endif

#ifndef ntohl
#define ntohl(A) ((((unsigned)(A) &0xff000000) >> 24) | \
	(((unsigned)(A) &0x00ff0000) >> 8) | \
	(((unsigned)(A) &0x0000ff00) << 8) | \
	(((unsigned)(A) &0x000000ff) << 24))
#endif

using namespace smpp::decoder;
using namespace smpp::constants::TLVtags;
using namespace smpp::constants::ErrorCode;

Decoder::Decoder(const QByteArray &nMassive):
	_Massive(nMassive),_Possition(0),_MaxPossition(0) {}

Decoder::Decoder(const Decoder &nDecoder):
	_Massive(nDecoder.getMassive()),
	_Possition(nDecoder.getMassivePossition()),
	_MaxPossition(nDecoder.getMaxMassivePossition()){}

void Decoder::setMassive(const QByteArray &nMassiveChar){
	_Massive = nMassiveChar;
}

const QByteArray Decoder::getMassive() const{
	return _Massive;
}

void Decoder::setMassivePossition(const int nPossition) {
	_Possition = nPossition;
}

const int Decoder::getMassivePossition() const{
	return _Possition;
}

void Decoder::setMaxMassivePossition(const int nMaxPossition){
	_MaxPossition = nMaxPossition;
}

const int Decoder::getMaxMassivePossition() const{
	return _MaxPossition;
}

void Decoder::clearMassive() {
	_Massive.clear();
	_Possition = 0;
	_MaxPossition = 0;
}

const quint32 Decoder::getLastError() const{
	return _LastError;
}

bool Decoder::_quint8(quint8 &nQuint8) {
	if(_Possition > _MaxPossition)
		return false;
	const quint8 nSizeof = 1;
	memcpy(&nQuint8,&_Massive.data()[_Possition],nSizeof);
	_Possition++;
	return true;
}

bool Decoder::_quint16(quint16 &nQquint16) {
	const quint8 nSizeof = 2;
	if(_Possition+nSizeof > _MaxPossition)
		return false;
	memcpy(&nQquint16,&_Massive.data()[_Possition],nSizeof);
	nQquint16 = ntohs(nQquint16);
	_Possition += nSizeof;
	return true;
}

bool Decoder::_quint32(quint32 &nUint32) {
	const quint8 nSizeof = 4;
	if(_Possition+nSizeof > _MaxPossition)
		return false;
	memcpy(&nUint32, &_Massive.data()[_Possition], nSizeof);
	nUint32 = ntohl(nUint32);
	_Possition += nSizeof;
	return true;
}

bool Decoder::_octetString(octetString &nOctetString,const quint16 nLength) {
	if((_Possition+nLength)>_MaxPossition)
		return false;
	nOctetString.clear();
	nOctetString.resize(nLength);
	for(int i =0;i<nLength;i++)
		nOctetString[i] = _Massive[_Possition++];
	return true;
}

bool Decoder::_CoctetString(CoctetString &nCoctetString) {
	int _TmpPossition(_Possition);
	int _MassLen(_MaxPossition);
	while(1){
		if(_TmpPossition>_MassLen)
			return false;
		if(_Massive[_TmpPossition++] == '\0')
			break;
	}
	nCoctetString.clear();
	_TmpPossition-=_Possition;
	nCoctetString.resize(_TmpPossition);
	for(int i=0;i<_TmpPossition;i++)
		nCoctetString[i] = _Massive[_Possition++];
	return true;
}

bool Decoder::_Header(Header &nHeader){
	quint32 buff(0);
	if(!_quint32(buff))
		return false;
	nHeader.setCommandLength(buff);
	if(!_quint32(buff))
		return false;
	nHeader.setCommandId(buff);
	if(!_quint32(buff))
		return false;
	nHeader.setCommandStatus(buff);
	if(!_quint32(buff))
		return false;
	nHeader.setSequenceNumber(buff);
	return true;
}

bool Decoder::_TLVbase(TLV &nTLV){
	quint16 buff(0);
	if(!_quint16(buff)){
		_LastError = ESME_RINVTLVSTREAM;
		return false;
	}
	nTLV.setTag(buff);
	if(!_quint16(buff)){
		_LastError = ESME_RINVTLVSTREAM;
		return false;
	}
	nTLV.setLength(buff);
	return true;
}

bool Decoder::_CancelBroadcastOptionalTLVs(const TLV &nTLV,
	CancelBroadcastOptionalTLVs &nCancelBroadcastOptionalTLVs) 
	{
	switch(nTLV.getTag()){
		case TAG_BROADCAST_CONTENT_TYPE:{
			if(nCancelBroadcastOptionalTLVs.getBroadcastContentType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())){
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BroadcastContentType *nBroadcastContentType = 
				new BroadcastContentType();
			nBroadcastContentType->setLength(nTLV.getLength());
			nCancelBroadcastOptionalTLVs.setBroadcastContentType(
				nBroadcastContentType);
			delete nBroadcastContentType;
			break;
		}
		case TAG_USER_MESSAGE_REFERENCE:{
			if(nCancelBroadcastOptionalTLVs.getUserMessageReference()) {
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UserMessageReference *nUserMessageReference = 
				new UserMessageReference(buff);
			nUserMessageReference->setLength(nTLV.getLength());
			nCancelBroadcastOptionalTLVs.setUserMessageReference(
				nUserMessageReference);
			delete nUserMessageReference;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_QueryBroadcastRequestOptionalTLVs(const TLV &nTLV,
	QueryBroadcastRequestOptionalTLVs &nQueryBroadcastRequestOptionalTLVs) {
	switch(nTLV.getTag()){
		case TAG_USER_MESSAGE_REFERENCE:{
			if(nQueryBroadcastRequestOptionalTLVs.getUserMessageReference()) {
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UserMessageReference *nUserMessageReference = 
				new UserMessageReference(buff);
			nUserMessageReference->setLength(nTLV.getLength());
			nQueryBroadcastRequestOptionalTLVs.setUserMessageReference(
				nUserMessageReference);
			delete nUserMessageReference;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_QueryBroadcastResponseOptionalTLVs(const TLV &nTLV,
	QueryBroadcastResponseOptionalTLVs &nQueryBroadcastResponseOptionalTLVs) 
	{
	switch(nTLV.getTag()){
		case TAG_BROADCAST_CONTENT_TYPE:{
			if(nQueryBroadcastResponseOptionalTLVs.getBroadcastEndTime()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			CoctetString buff;
			if(!_CoctetString(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BroadcastEndTime *nBroadcastEndTime = 
				new BroadcastEndTime(buff);
			nBroadcastEndTime->setLength(nTLV.getLength());
			nQueryBroadcastResponseOptionalTLVs.setBroadcastEndTime(
				nBroadcastEndTime);
			delete nBroadcastEndTime;
			break;
		}
		case TAG_USER_MESSAGE_REFERENCE:{
			if(nQueryBroadcastResponseOptionalTLVs.getUserMessageReference()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UserMessageReference *nUserMessageReference = 
				new UserMessageReference(buff);
			nUserMessageReference->setLength(nTLV.getLength());
			nQueryBroadcastResponseOptionalTLVs.setUserMessageReference(
				nUserMessageReference);
			delete nUserMessageReference;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_MessageReplacementTLVs(const TLV &nTLV,
	MessageReplacementTLVs &nMessageReplacementTLVs){
	switch(nTLV.getTag()){
		case TAG_USER_MESSAGE_REFERENCE:{
			if(nMessageReplacementTLVs.getMessagePayload()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MessagePayload *nMessagePayload = 
				new MessagePayload(buff);
			nMessagePayload->setLength(nTLV.getLength());
			nMessageReplacementTLVs.setMessagePayload(
				nMessagePayload);
			delete nMessagePayload;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_BroadcastRequestOptionalTLVs(const TLV &nTLV,
	BroadcastRequestOptionalTLVs &nBroadcastRequestOptionalTLVs) {
	switch(nTLV.getTag()) {
		case TAG_ALERT_ON_MESSAGE_DELIVERY: {
			if(nBroadcastRequestOptionalTLVs.getAlertOnMessageDelivery()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			AlertOnMessageDelivery *nAlertOnMessageDelivery = 
				new AlertOnMessageDelivery(buff);
			nAlertOnMessageDelivery->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setAlertOnMessageDelivery(
				nAlertOnMessageDelivery);
			delete nAlertOnMessageDelivery;
			break;
		}
		case TAG_BROADCAST_CHANNEL_INDICATOR: {
			if(nBroadcastRequestOptionalTLVs.getBroadcastChannelIndicator()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BroadcastChannelIndicator *nBroadcastChannelIndicator = 
				new BroadcastChannelIndicator(buff);
			nBroadcastChannelIndicator->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setBroadcastChannelIndicator(
				nBroadcastChannelIndicator);
			delete nBroadcastChannelIndicator;
			break;
		}
		case TAG_BROADCAST_CONTENT_TYPE_INFO:{
			if(nBroadcastRequestOptionalTLVs.getBroadcastContentTypeInfo()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BroadcastContentTypeInfo *nBroadcastContentTypeInfo = 
				new BroadcastContentTypeInfo(buff);
			nBroadcastContentTypeInfo->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setBroadcastContentTypeInfo(
				nBroadcastContentTypeInfo);
			delete nBroadcastContentTypeInfo;
			break;
		}
		case TAG_BROADCAST_MESSAGE_CLASS:{
			if(nBroadcastRequestOptionalTLVs.getBroadcastMessageClass()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BroadcastMessageClass *nBroadcastMessageClass = 
				new BroadcastMessageClass(buff);
			nBroadcastMessageClass->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setBroadcastMessageClass(
				nBroadcastMessageClass);
			delete nBroadcastMessageClass;
			break;
		}
		case TAG_BROADCAST_SERVICE_GROUP:{
			if(nBroadcastRequestOptionalTLVs.getBroadcastServiceGroup()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BroadcastServiceGroup *nBroadcastServiceGroup = 
				new BroadcastServiceGroup(buff);
			nBroadcastServiceGroup->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setBroadcastServiceGroup(
				nBroadcastServiceGroup);
			delete nBroadcastServiceGroup;
			break;
		}
		case TAG_CALLBACK_NUM:{
			if(nBroadcastRequestOptionalTLVs.getCallbackNum()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNum *nCallbackNum = 
				new CallbackNum(buff);
			nCallbackNum->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setCallbackNum(
				nCallbackNum);
			delete nCallbackNum;
			break;
		}
		case TAG_CALLBACK_NUM_ATAG:{
			if(nBroadcastRequestOptionalTLVs.getCallbackNumAtag()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNumAtag *nCallbackNumAtag = 
				new CallbackNumAtag(buff);
			nCallbackNumAtag->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setCallbackNumAtag(
				nCallbackNumAtag);
			delete nCallbackNumAtag;
			break;
		}
		case TAG_CALLBACK_NUM_PRES_IND:{
			if(nBroadcastRequestOptionalTLVs.getCallbackNumPresInd()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNumPresInd *nCallbackNumPresInd = 
				new CallbackNumPresInd(buff);
			nCallbackNumPresInd->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setCallbackNumPresInd(
				nCallbackNumPresInd);
			delete nCallbackNumPresInd;
			break;
		}
		case TAG_DEST_ADDR_SUBUNIT:{
			if(nBroadcastRequestOptionalTLVs.getDestAddrSubunit()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrSubunit *nDestAddrSubunit = new DestAddrSubunit(buff);
			nDestAddrSubunit->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setDestAddrSubunit(
				nDestAddrSubunit);
			delete nDestAddrSubunit;
			break;
		}
		case TAG_DEST_SUBADDRESS:{
			if(nBroadcastRequestOptionalTLVs.getDestSubaddress()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestSubaddress *nDestSubaddress = new DestSubaddress(buff);
			nDestSubaddress->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setDestSubaddress(
				nDestSubaddress);
			delete nDestSubaddress;
			break;
		}
		case TAG_DEST_PORT:{
			if(nBroadcastRequestOptionalTLVs.getDestPort()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestPort *nDestPort = new DestPort(buff);
			nDestPort->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setDestPort(nDestPort);
			delete nDestPort;
			break;
		}
		case TAG_DISPLAY_TIME:{
			if(nBroadcastRequestOptionalTLVs.getDisplayTime()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DisplayTime *nDisplayTime = 
				new DisplayTime(buff);
			nDisplayTime->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setDisplayTime(nDisplayTime);
			delete nDisplayTime;
			break;
		}
		case TAG_LANGUAGE_INDICATOR:{
			if(nBroadcastRequestOptionalTLVs.getLanguageIndicator()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			LanguageIndicator *nLanguageIndicator = 
				new LanguageIndicator(buff);
			nLanguageIndicator->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setLanguageIndicator(
				nLanguageIndicator);
			delete nLanguageIndicator;
			break;
		}
		case TAG_MESSAGE_PAYLOAD:{
			if(nBroadcastRequestOptionalTLVs.getMessagePayload()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MessagePayload *nMessagePayload = 
				new MessagePayload(buff);
			nMessagePayload->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setMessagePayload(
				nMessagePayload);
			delete nMessagePayload;
			break;
		}
		case TAG_MS_VALIDITY:{
			if(nBroadcastRequestOptionalTLVs.getMsValidity()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MsValidity *nMsValidity = 
				new MsValidity(buff);
			nMsValidity->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setMsValidity(
				nMsValidity);
			delete nMsValidity;
			break;
		}
		case TAG_PAYLOAD_TYPE:{
			if(nBroadcastRequestOptionalTLVs.getPayloadType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			PayloadType *nPayloadType = 
				new PayloadType(buff);
			nPayloadType->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setPayloadType(
				nPayloadType);
			delete nPayloadType;
			break;
		}
		case TAG_PRIVACY_INDICATOR:{
			if(nBroadcastRequestOptionalTLVs.getPrivacyIndicator()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			PrivacyIndicator *nPrivacyIndicator = 
				new PrivacyIndicator(buff);
			nPrivacyIndicator->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setPrivacyIndicator(
				nPrivacyIndicator);
			delete nPrivacyIndicator;
			break;
		}
		case TAG_SMS_SIGNAL:{
			if(nBroadcastRequestOptionalTLVs.getSmsSignal()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SmsSignal *nSmsSignal = new SmsSignal(buff);
			nSmsSignal->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setSmsSignal(
				nSmsSignal);
			delete nSmsSignal;
			break;
		}
		case TAG_SOURCE_ADDR_SUBUNIT:{
			if(nBroadcastRequestOptionalTLVs.getSourceAddrSubunit()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceAddrSubunit *nSourceAddrSubunit = 
				new SourceAddrSubunit(buff);
			nSourceAddrSubunit->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setSourceAddrSubunit(
				nSourceAddrSubunit);
			delete nSourceAddrSubunit;
			break;
		}
		case TAG_SOURCE_PORT:{
			if(nBroadcastRequestOptionalTLVs.getSourcePort()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourcePort *nSourcePort = new SourcePort(buff);
			nSourcePort->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setSourcePort(nSourcePort);
			delete nSourcePort;
			break;
		}
		case TAG_SOURCE_SUBADDRESS:{
			if(nBroadcastRequestOptionalTLVs.getSourceSubaddress()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceSubaddress *nSourceSubaddress = 
				new SourceSubaddress(buff);
			nSourceSubaddress->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setSourceSubaddress(
				nSourceSubaddress);
			delete nSourceSubaddress;
			break;
		}
		case TAG_USER_MESSAGE_REFERENCE:{		
			if(nBroadcastRequestOptionalTLVs.getUserMessageReference()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UserMessageReference *nUserMessageReference = 
				new UserMessageReference(buff);
			nUserMessageReference->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setUserMessageReference(
				nUserMessageReference);
			delete nUserMessageReference;
			break;
		}
		case TAG_BROADCAST_ERROR_STATUS:{
			if(nBroadcastRequestOptionalTLVs.getBroadcastErrorStatus()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint32 buff;
			if(!_quint32(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BroadcastErrorStatus *nBroadcastErrorStatus = 
				new BroadcastErrorStatus(buff);
			nBroadcastErrorStatus->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setBroadcastErrorStatus(
				nBroadcastErrorStatus);
			delete nBroadcastErrorStatus;
			break;
		}
		case TAG_BROADCAST_AREA_IDENTIFIER:{
			if(nBroadcastRequestOptionalTLVs.getFailedBroadcastAreaIdentifier()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength()&0x00FF)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			FailedBroadcastAreaIdentifier *nFailedBroadcastAreaIdentifier = 
				new FailedBroadcastAreaIdentifier(buff);
			nFailedBroadcastAreaIdentifier->setLength(nTLV.getLength());
			nBroadcastRequestOptionalTLVs.setFailedBroadcastAreaIdentifier(
				nFailedBroadcastAreaIdentifier);
			delete nFailedBroadcastAreaIdentifier;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_BroadcastResponseOptionalTLVs(const TLV &nTLV,
	BroadcastResponseOptionalTLVs &nBroadcastResponseOptionalTLVs){
	switch(nTLV.getTag()){
		case TAG_BROADCAST_ERROR_STATUS:{
			if(nBroadcastResponseOptionalTLVs.getBroadcastErrorStatus()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint32 buff;
			if(!_quint32(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BroadcastErrorStatus *nBroadcastErrorStatus = 
				new BroadcastErrorStatus(buff);
			nBroadcastErrorStatus->setLength(nTLV.getLength());
			nBroadcastResponseOptionalTLVs.setBroadcastErrorStatus(
				nBroadcastErrorStatus);
			delete nBroadcastErrorStatus;
			break;
		}
		case TAG_BROADCAST_AREA_IDENTIFIER:{
			if(nBroadcastResponseOptionalTLVs.getFailedBroadcastAreaIdentifier()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength()&0x00FF)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			FailedBroadcastAreaIdentifier *nFailedBroadcastAreaIdentifier = 
				new FailedBroadcastAreaIdentifier(buff);
			nFailedBroadcastAreaIdentifier->setLength(nTLV.getLength());
			nBroadcastResponseOptionalTLVs.setFailedBroadcastAreaIdentifier(
				nFailedBroadcastAreaIdentifier);
			delete nFailedBroadcastAreaIdentifier;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_MessageDeliveryRequestTLVs(const TLV &nTLV,
	MessageDeliveryRequestTLVs &nMessageDeliveryRequestTLVs) 
	{
	switch(nTLV.getTag()){
		case TAG_CALLBACK_NUM:{
			if(nMessageDeliveryRequestTLVs.getCallbackNum()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNum *nCallbackNum = new CallbackNum(buff);
			nCallbackNum->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setCallbackNum(nCallbackNum);
			delete nCallbackNum;
			break;
		}
		case TAG_CALLBACK_NUM_ATAG:{
			if(nMessageDeliveryRequestTLVs.getCallbackNumAtag()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNumAtag *nCallbackNumAtag = new CallbackNumAtag(buff);
			nCallbackNumAtag->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setCallbackNumAtag(
				nCallbackNumAtag);
			delete nCallbackNumAtag;
			break;
		}
		case TAG_CALLBACK_NUM_PRES_IND:{
			if(nMessageDeliveryRequestTLVs.getCallbackNumPresInd()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNumPresInd *nCallbackNumPresInd = 
				new CallbackNumPresInd(buff);
			nCallbackNumPresInd->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setCallbackNumPresInd(
				nCallbackNumPresInd);
			delete nCallbackNumPresInd;
			break;
		}
		case TAG_DEST_ADDR_NP_COUNTRY:{
			if(nMessageDeliveryRequestTLVs.getDestAddrNpCountry()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrNpCountry *nDestAddrNpCountry = 
				new DestAddrNpCountry(buff);
			nDestAddrNpCountry->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDestAddrNpCountry(
				nDestAddrNpCountry);
			delete nDestAddrNpCountry;
			break;
		}
		case TAG_DEST_ADDR_NP_INFORMATION:{
			if(nMessageDeliveryRequestTLVs.getDestAddrNpInformation()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrNpInformation *nDestAddrNpInformation = 
				new DestAddrNpInformation(buff);
			nDestAddrNpInformation->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDestAddrNpInformation(
				nDestAddrNpInformation);
			delete nDestAddrNpInformation;
			break;
		}
		case TAG_DEST_ADDR_NP_RESOLUTION:{
			if(nMessageDeliveryRequestTLVs.getDestAddrNpResolution()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrNpResolution *nDestAddrNpResolution = 
				new DestAddrNpResolution(buff);
			nDestAddrNpResolution->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDestAddrNpResolution(
				nDestAddrNpResolution);
			delete nDestAddrNpResolution;
			break;
		}
		case TAG_DEST_ADDR_SUBUNIT:{
			if(nMessageDeliveryRequestTLVs.getDestAddrSubunit()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrSubunit *nDestAddrSubunit = 
				new DestAddrSubunit(buff);
			nDestAddrSubunit->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDestAddrSubunit(
				nDestAddrSubunit);
			delete nDestAddrSubunit;
			break;
		}
		case TAG_DEST_NETWORK_ID:{
			if(nMessageDeliveryRequestTLVs.getDestNetworkId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			CoctetString buff;
			if(!_CoctetString(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestNetworkId *nDestNetworkId = new DestNetworkId(buff);
			nDestNetworkId->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDestNetworkId(nDestNetworkId);
			delete nDestNetworkId;
			break;
		}
		case TAG_DEST_NODE_ID:{
			if(nMessageDeliveryRequestTLVs.getDestNodeId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestNodeId *nDestNodeId = new DestNodeId(buff);
			nDestNodeId->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDestNodeId(nDestNodeId);
			delete nDestNodeId;
			break;
		}
		case TAG_DEST_SUBADDRESS:{
			if(nMessageDeliveryRequestTLVs.getDestSubaddress()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestSubaddress *nDestSubaddress = new DestSubaddress(buff);
			nDestSubaddress->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDestSubaddress(nDestSubaddress);
			delete nDestSubaddress;
			break;
		}
		case TAG_DEST_PORT:{
			if(nMessageDeliveryRequestTLVs.getDestPort()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestPort *nDestPort = new DestPort(buff);
			nDestPort->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDestPort(
				nDestPort);
			delete nDestPort;
			break;
		}
		case TAG_DPF_RESULT:{
			if(nMessageDeliveryRequestTLVs.getDpfResult()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DpfResult *nDpfResult = new DpfResult(buff);
			nDpfResult->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setDpfResult(nDpfResult);
			delete nDpfResult;
			break;
		}
		case TAG_ITS_REPLY_TYPE:{
			if(nMessageDeliveryRequestTLVs.getItsReplyType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			ItsReplyType *nItsReplyType = 
				new ItsReplyType(buff);
			nItsReplyType->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setItsReplyType(
				nItsReplyType);
			delete nItsReplyType;
			break;
		}
		case TAG_ITS_SESSION_INFO:{
			if(nMessageDeliveryRequestTLVs.getItsSessionInfo()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			ItsSessionInfo *nItsSessionInfo = new ItsSessionInfo(buff);
			nItsSessionInfo->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setItsSessionInfo(nItsSessionInfo);
			delete nItsSessionInfo;
			break;
		}
		case TAG_LANGUAGE_INDICATOR:{
			if(nMessageDeliveryRequestTLVs.getLanguageIndicator()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			LanguageIndicator *nLanguageIndicator = 
				new LanguageIndicator(buff);
			nLanguageIndicator->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setLanguageIndicator(
				nLanguageIndicator);
			delete nLanguageIndicator;
			break;
		}
		case TAG_MESSAGE_PAYLOAD:{
			if(nMessageDeliveryRequestTLVs.getMessagePayload()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MessagePayload *nMessagePayload = new MessagePayload(buff);
			nMessagePayload->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setMessagePayload(nMessagePayload);
			delete nMessagePayload;
			break;
		}
		case TAG_MESSAGE_STATE:{
			if(nMessageDeliveryRequestTLVs.getMessageState()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MessageState *nMessageState = 
				new MessageState(buff);
			nMessageState->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setMessageState(
				nMessageState);
			delete nMessageState;
			break;
		}
		case TAG_NETWORK_ERROR_CODE:{
			if(nMessageDeliveryRequestTLVs.getNetworkErrorCode()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			NetworkErrorCode *nNetworkErrorCode = 
				new NetworkErrorCode(buff);
			nNetworkErrorCode->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setNetworkErrorCode(
				nNetworkErrorCode);
			delete nNetworkErrorCode;
			break;
		}
		case TAG_PAYLOAD_TYPE:{
			if(nMessageDeliveryRequestTLVs.getPayloadType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			PayloadType *nPayloadType = new PayloadType(buff);
			nPayloadType->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setPayloadType(nPayloadType);
			delete nPayloadType;
			break;
		}
		case TAG_PRIVACY_INDICATOR:{
			if(nMessageDeliveryRequestTLVs.getPrivacyIndicator()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			PrivacyIndicator *nPrivacyIndicator = 
				new PrivacyIndicator(buff);
			nPrivacyIndicator->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setPrivacyIndicator(
				nPrivacyIndicator);
			delete nPrivacyIndicator;
			break;
		}
		case TAG_BROADCAST_ERROR_STATUS:{
			if(nMessageDeliveryRequestTLVs.getReceiptedMessageId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			CoctetString buff;
			if(!_CoctetString(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			ReceiptedMessageId *nReceiptedMessageId = 
				new ReceiptedMessageId(buff);
			nReceiptedMessageId->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setReceiptedMessageId(
				nReceiptedMessageId);
			delete nReceiptedMessageId;
			break;
		}
		case TAG_SAR_MSG_REF_NUM:{
			if(nMessageDeliveryRequestTLVs.getSarMsgRefNum()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SarMsgRefNum *nSarMsgRefNum = new SarMsgRefNum(buff);
			nSarMsgRefNum->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setSarMsgRefNum(nSarMsgRefNum);
			delete nSarMsgRefNum;
			break;
		}
		case TAG_SAR_SEGMENT_SEQNUM:{
			if(nMessageDeliveryRequestTLVs.getSarSegmentSeqnum()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SarSegmentSeqnum *nSarSegmentSeqnum = 
				new SarSegmentSeqnum(buff);
			nSarSegmentSeqnum->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setSarSegmentSeqnum(
				nSarSegmentSeqnum);
			delete nSarSegmentSeqnum;
			break;
		}
		case TAG_SAR_TOTAL_SEGMENTS:{
			if(nMessageDeliveryRequestTLVs.getSarTotalSegments()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SarTotalSegments *nSarTotalSegments = 
				new SarTotalSegments(buff);
			nSarTotalSegments->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setSarTotalSegments(
				nSarTotalSegments);
			delete nSarTotalSegments;
			break;
		}
		case TAG_SOURCE_ADDR_SUBUNIT:{
			if(nMessageDeliveryRequestTLVs.getSourceAddrSubunit()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceAddrSubunit *nSourceAddrSubunit = 
				new SourceAddrSubunit(buff);
			nSourceAddrSubunit->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setSourceAddrSubunit(
				nSourceAddrSubunit);
			delete nSourceAddrSubunit;
			break;
		}
		case TAG_SOURCE_NETWORK_ID:{
			if(nMessageDeliveryRequestTLVs.getSourceNetworkId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			CoctetString buff;
			if(!_CoctetString(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceNetworkId *nSourceNetworkId = new SourceNetworkId(buff);
			nSourceNetworkId->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setSourceNetworkId(
				nSourceNetworkId);
			delete nSourceNetworkId;
			break;
		}
		case TAG_SOURCE_NODE_ID:{
			if(nMessageDeliveryRequestTLVs.getSourceNodeId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceNodeId *nSourceNodeId = new SourceNodeId(buff);
			nSourceNodeId->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setSourceNodeId(nSourceNodeId);
			delete nSourceNodeId;
			break;
		}
		case TAG_SOURCE_PORT:{
			if(nMessageDeliveryRequestTLVs.getSourcePort()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourcePort *nSourcePort = new SourcePort(buff);
			nSourcePort->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setSourcePort(nSourcePort);
			delete nSourcePort;
			break;
		}
		case TAG_SOURCE_SUBADDRESS:{
			if(nMessageDeliveryRequestTLVs.getSourceSubaddress()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceSubaddress *nSourceSubaddress = 
				new SourceSubaddress(buff);
			nSourceSubaddress->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setSourceSubaddress(
				nSourceSubaddress);
			delete nSourceSubaddress;
			break;
		}
		case TAG_USER_MESSAGE_REFERENCE:{
			if(nMessageDeliveryRequestTLVs.getUserMessageReference()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UserMessageReference *nUserMessageReference = 
				new UserMessageReference(buff);
			nUserMessageReference->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setUserMessageReference(
				nUserMessageReference);
			delete nUserMessageReference;
			break;
		}
		case TAG_USER_RESPONSE_CODE:{
			if(nMessageDeliveryRequestTLVs.getUserResponseCode()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UserResponseCode *nUserResponseCode = 
				new UserResponseCode(buff);
			nUserResponseCode->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setUserResponseCode(
				nUserResponseCode);
			delete nUserResponseCode;
			break;
		}
		case TAG_USSD_SERVICE_OP:{
			if(nMessageDeliveryRequestTLVs.getUssdServiceOp()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UssdServiceOp *nUssdServiceOp = new UssdServiceOp(buff);
			nUssdServiceOp->setLength(nTLV.getLength());
			nMessageDeliveryRequestTLVs.setUssdServiceOp(nUssdServiceOp);
			delete nUssdServiceOp;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_MessageDeliveryResponseTLVs(const TLV &nTLV,
	MessageDeliveryResponseTLVs &nMessageDeliveryResponseTLVs) {
	switch(nTLV.getTag()){
		case TAG_ADDITIONAL_STATUS_INFO_TEXT:{
			if(nMessageDeliveryResponseTLVs.getAdditionalStatusInfoText()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			CoctetString buff;
			if(!_CoctetString(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			AdditionalStatusInfoText *nAdditionalStatusInfoText = 
				new AdditionalStatusInfoText(buff);
			nAdditionalStatusInfoText->setLength(nTLV.getLength());
			nMessageDeliveryResponseTLVs.setAdditionalStatusInfoText(
				nAdditionalStatusInfoText);
			delete nAdditionalStatusInfoText;
			break;
		}
		case TAG_DELIVERY_FAILURE_REASON:{
			if(nMessageDeliveryResponseTLVs.getDeliveryFailureReason()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DeliveryFailureReason *nDeliveryFailureReason = 
				new DeliveryFailureReason(buff);
			nDeliveryFailureReason->setLength(nTLV.getLength());
			nMessageDeliveryResponseTLVs.setDeliveryFailureReason(
				nDeliveryFailureReason);
			delete nDeliveryFailureReason;
			break;
		}
		case TAG_NETWORK_ERROR_CODE:{
			if(nMessageDeliveryResponseTLVs.getNetworkErrorCode()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			NetworkErrorCode *nNetworkErrorCode = new NetworkErrorCode(buff);
			nNetworkErrorCode->setLength(nTLV.getLength());
			nMessageDeliveryResponseTLVs.setNetworkErrorCode(
				nNetworkErrorCode);
			delete nNetworkErrorCode;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_MessageSubmissionRequestTLVs(const TLV &nTLV,
	MessageSubmissionRequestTLVs &nMessageSubmissionRequestTLVs) 
	{
	switch(nTLV.getTag()){
		case TAG_ALERT_ON_MESSAGE_DELIVERY:{
			if(nMessageSubmissionRequestTLVs.getAlertOnMessageDelivery()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			AlertOnMessageDelivery *nAlertOnMessageDelivery = 
				new AlertOnMessageDelivery(buff);
			nAlertOnMessageDelivery->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setAlertOnMessageDelivery(
				nAlertOnMessageDelivery);
			delete nAlertOnMessageDelivery;
			break;
		}
		case TAG_BILLING_IDENTIFICATION:{
			if(nMessageSubmissionRequestTLVs.getBillingIdentification()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			BillingIdentification *nBillingIdentification = 
				new BillingIdentification(buff);
			nBillingIdentification->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setBillingIdentification(
				nBillingIdentification);
			delete nBillingIdentification;
			break;
		}
		case TAG_CALLBACK_NUM:{
			if(nMessageSubmissionRequestTLVs.getCallbackNum()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNum *nCallbackNum = new CallbackNum(buff);
			nCallbackNum->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setCallbackNum(nCallbackNum);
			delete nCallbackNum;
			break;
		}
		case TAG_CALLBACK_NUM_ATAG:{
			if(nMessageSubmissionRequestTLVs.getCallbackNumAtag()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNumAtag *nCallbackNumAtag = 
				new CallbackNumAtag(buff);
			nCallbackNumAtag->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setCallbackNumAtag(
				nCallbackNumAtag);
			delete nCallbackNumAtag;
			break;
		}
		case TAG_CALLBACK_NUM_PRES_IND:{
			if(nMessageSubmissionRequestTLVs.getCallbackNumPresInd()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CallbackNumPresInd *nCallbackNumPresInd = 
				new CallbackNumPresInd(buff);
			nCallbackNumPresInd->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setCallbackNumPresInd(
				nCallbackNumPresInd);
			delete nCallbackNumPresInd;
			break;
		}
		case TAG_DEST_ADDR_NP_COUNTRY:{
			if(nMessageSubmissionRequestTLVs.getDestAddrNpCountry()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrNpCountry *nDestAddrNpCountry = 
				new DestAddrNpCountry(buff);
			nDestAddrNpCountry->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestAddrNpCountry(
				nDestAddrNpCountry);
			delete nDestAddrNpCountry;
			break;
		}
		case TAG_DEST_ADDR_NP_INFORMATION:{
			if(nMessageSubmissionRequestTLVs.getDestAddrNpInformation()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrNpInformation *nDestAddrNpInformation = 
				new DestAddrNpInformation(buff);
			nDestAddrNpInformation->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestAddrNpInformation(
				nDestAddrNpInformation);
			delete nDestAddrNpInformation;
			break;
		}
		case TAG_DEST_ADDR_NP_RESOLUTION:{
			if(nMessageSubmissionRequestTLVs.getDestAddrNpResolution()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrNpResolution *nDestAddrNpResolution = 
				new DestAddrNpResolution(buff);
			nDestAddrNpResolution->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestAddrNpResolution(
				nDestAddrNpResolution);
			delete nDestAddrNpResolution;
			break;
		}
		case TAG_DEST_ADDR_SUBUNIT:{
			if(nMessageSubmissionRequestTLVs.getDestAddrSubunit()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestAddrSubunit *nDestAddrSubunit = 
				new DestAddrSubunit(buff);
			nDestAddrSubunit->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestAddrSubunit(
				nDestAddrSubunit);
			delete nDestAddrSubunit;
			break;
		}
		case TAG_DEST_BEARER_TYPE:{
			if(nMessageSubmissionRequestTLVs.getDestBearerType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestBearerType *nDestBearerType = 
				new DestBearerType(buff);
			nDestBearerType->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestBearerType(
				nDestBearerType);
			delete nDestBearerType;
			break;
		}
		case TAG_DEST_NETWORK_ID:{
			if(nMessageSubmissionRequestTLVs.getDestNetworkId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			CoctetString buff;
			if(!_CoctetString(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestNetworkId *nDestNetworkId = 
				new DestNetworkId(buff);
			nDestNetworkId->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestNetworkId(
				nDestNetworkId);
			delete nDestNetworkId;
			break;
		}
		case TAG_DEST_NETWORK_TYPE:{
			if(nMessageSubmissionRequestTLVs.getDestNetworkType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestNetworkType *nDestNetworkType = 
				new DestNetworkType(buff);
			nDestNetworkType->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestNetworkType(
				nDestNetworkType);
			delete nDestNetworkType;
			break;
		}
		case TAG_DEST_NODE_ID:{
			if(nMessageSubmissionRequestTLVs.getDestNodeId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestNodeId *nDestNodeId = new DestNodeId(buff);
			nDestNodeId->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestNodeId(nDestNodeId);
			delete nDestNodeId;
			break;
		}
		case TAG_DEST_SUBADDRESS:{
			if(nMessageSubmissionRequestTLVs.getDestSubaddress()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestSubaddress *nDestSubaddress = new DestSubaddress(buff);
			nDestSubaddress->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestSubaddress(
				nDestSubaddress);
			delete nDestSubaddress;
			break;
		}
		case TAG_DEST_TELEMATICS_ID:{
			if(nMessageSubmissionRequestTLVs.getDestTelematicsId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestTelematicsId *nDestTelematicsId = 
				new DestTelematicsId(buff);
			nDestTelematicsId->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestTelematicsId(
				nDestTelematicsId);
			delete nDestTelematicsId;
			break;
		}
		case TAG_DEST_PORT:{
			if(nMessageSubmissionRequestTLVs.getDestPort()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DestPort *nDestPort = new DestPort(buff);
			nDestPort->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDestPort(nDestPort);
			delete nDestPort;
			break;
		}
		case TAG_DPF_RESULT:{
			if(nMessageSubmissionRequestTLVs.getDisplayTime()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DisplayTime *nDisplayTime = new DisplayTime(buff);
			nDisplayTime->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setDisplayTime(nDisplayTime);
			delete nDisplayTime;
			break;
		}
		case TAG_ITS_REPLY_TYPE:{
			if(nMessageSubmissionRequestTLVs.getItsReplyType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			ItsReplyType *nItsReplyType = new ItsReplyType(buff);
			nItsReplyType->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setItsReplyType(nItsReplyType);
			delete nItsReplyType;
			break;
		}
		case TAG_ITS_SESSION_INFO:{
			if(nMessageSubmissionRequestTLVs.getItsSessionInfo()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			ItsSessionInfo *nItsSessionInfo = new ItsSessionInfo(buff);
			nItsSessionInfo->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setItsSessionInfo(
				nItsSessionInfo);
			delete nItsSessionInfo;
			break;
		}
		case TAG_LANGUAGE_INDICATOR:{
			if(nMessageSubmissionRequestTLVs.getLanguageIndicator()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			LanguageIndicator *nLanguageIndicator = 
				new LanguageIndicator(buff);
			nLanguageIndicator->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setLanguageIndicator(
				nLanguageIndicator);
			delete nLanguageIndicator;
			break;
		}
		case TAG_MESSAGE_PAYLOAD:{
			if(nMessageSubmissionRequestTLVs.getMessagePayload()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MessagePayload *nMessagePayload = new MessagePayload(buff);
			nMessagePayload->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setMessagePayload(
				nMessagePayload);
			delete nMessagePayload;
			break;
		}
		case TAG_MORE_MESSAGES_TO_SEND:{
			if(nMessageSubmissionRequestTLVs.getMoreMessagesToSend()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MoreMessagesToSend *nMoreMessagesToSend = 
				new MoreMessagesToSend(buff);
			nMoreMessagesToSend->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setMoreMessagesToSend(
				nMoreMessagesToSend);
			delete nMoreMessagesToSend;
			break;
		}
		case TAG_MS_MSG_WAIT_FACILITIES:{
			if(nMessageSubmissionRequestTLVs.getMsMsgWaitFacilities()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MsMsgWaitFacilities *nMsMsgWaitFacilities = 
				new MsMsgWaitFacilities(buff);
			nMsMsgWaitFacilities->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setMsMsgWaitFacilities(
				nMsMsgWaitFacilities);
			delete nMsMsgWaitFacilities;
			break;
		}
		case TAG_MS_VALIDITY:{
			if(nMessageSubmissionRequestTLVs.getMsValidity()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			MsValidity *nMsValidity = new MsValidity(buff);
			nMsValidity->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setMsValidity(nMsValidity);
			delete nMsValidity;
			break;
		}
		case TAG_NUMBER_OF_MESSAGES:{
			if(nMessageSubmissionRequestTLVs.getNumberOfMessages()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			NumberOfMessages *nNumberOfMessages = 
				new NumberOfMessages(buff);
			nNumberOfMessages->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setNumberOfMessages(
				nNumberOfMessages);
			delete nNumberOfMessages;
			break;
		}
		case TAG_PAYLOAD_TYPE:{
			if(nMessageSubmissionRequestTLVs.getPayloadType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			PayloadType *nPayloadType = new PayloadType(buff);
			nPayloadType->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setPayloadType(nPayloadType);
			delete nPayloadType;
			break;
		}
		case TAG_PRIVACY_INDICATOR:{
			if(nMessageSubmissionRequestTLVs.getPrivacyIndicator()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			PrivacyIndicator *nPrivacyIndicator = 
				new PrivacyIndicator(buff);
			nPrivacyIndicator->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setPrivacyIndicator(
				nPrivacyIndicator);
			delete nPrivacyIndicator;
			break;
		}
		case TAG_QOS_TIME_TO_LIVE:{
			if(nMessageSubmissionRequestTLVs.getQosTimeToLive()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint32 buff;
			if(!_quint32(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			QosTimeToLive *nQosTimeToLive = new QosTimeToLive(buff);
			nQosTimeToLive->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setQosTimeToLive(
				nQosTimeToLive);
			delete nQosTimeToLive;
			break;
		}
		case TAG_SAR_MSG_REF_NUM:{
			if(nMessageSubmissionRequestTLVs.getSarMsgRefNum()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SarMsgRefNum *nSarMsgRefNum = new SarMsgRefNum(buff);
			nSarMsgRefNum->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSarMsgRefNum(nSarMsgRefNum);
			delete nSarMsgRefNum;
			break;
		}
		case TAG_SAR_SEGMENT_SEQNUM:{
			if(nMessageSubmissionRequestTLVs.getSarSegmentSeqnum()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SarSegmentSeqnum *nSarSegmentSeqnum = 
				new SarSegmentSeqnum(buff);
			nSarSegmentSeqnum->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSarSegmentSeqnum(
				nSarSegmentSeqnum);
			delete nSarSegmentSeqnum;
			break;
		}
		case TAG_SAR_TOTAL_SEGMENTS:{
			if(nMessageSubmissionRequestTLVs.getSarTotalSegments()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SarTotalSegments *nSarTotalSegments = 
				new SarTotalSegments(buff);
			nSarTotalSegments->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSarTotalSegments(
				nSarTotalSegments);
			delete nSarTotalSegments;
			break;
		}
		case TAG_SET_DPF:{
			if(nMessageSubmissionRequestTLVs.getSetDpf()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SetDpf *nSetDpf = new SetDpf(buff);
			nSetDpf->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSetDpf(nSetDpf);
			delete nSetDpf;
			break;
		}
		case TAG_SMS_SIGNAL:{
			if(nMessageSubmissionRequestTLVs.getSmsSignal()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SmsSignal *nSmsSignal = new SmsSignal(buff);
			nSmsSignal->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSmsSignal(nSmsSignal);
			delete nSmsSignal;
			break;
		}
		case TAG_SOURCE_ADDR_SUBUNIT:{
			if(nMessageSubmissionRequestTLVs.getSourceAddrSubunit()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceAddrSubunit *nSourceAddrSubunit = 
				new SourceAddrSubunit(buff);
			nSourceAddrSubunit->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSourceAddrSubunit(
				nSourceAddrSubunit);
			delete nSourceAddrSubunit;
			break;
		}
		case TAG_SOURCE_BEARER_TYPE:{
			if(nMessageSubmissionRequestTLVs.getSourceBearerType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceBearerType *nSourceBearerType = 
				new SourceBearerType(buff);
			nSourceBearerType->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSourceBearerType(
				nSourceBearerType);
			delete nSourceBearerType;
			break;
		}
		case TAG_SOURCE_NETWORK_ID:{
			if(nMessageSubmissionRequestTLVs.getSourceNetworkId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			CoctetString buff;
			if(!_CoctetString(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceNetworkId *nSourceNetworkId = new SourceNetworkId(buff);
			nSourceNetworkId->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSourceNetworkId(
				nSourceNetworkId);
			delete nSourceNetworkId;
			break;
		}
		case TAG_SOURCE_NETWORK_TYPE:{
			if(nMessageSubmissionRequestTLVs.getSourceNetworkType()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceNetworkType *nSourceNetworkType = 
				new SourceNetworkType(buff);
			nSourceNetworkType->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSourceNetworkType(
				nSourceNetworkType);
			delete nSourceNetworkType;
			break;
		}
		case TAG_SOURCE_NODE_ID:{
			if(nMessageSubmissionRequestTLVs.getSourceNodeId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceNodeId *nSourceNodeId = new SourceNodeId(buff);
			nSourceNodeId->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSourceNodeId(nSourceNodeId);
			delete nSourceNodeId;
			break;
		}
		case TAG_SOURCE_PORT:{
			if(nMessageSubmissionRequestTLVs.getSourcePort()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourcePort *nSourcePort = new SourcePort(buff);
			nSourcePort->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSourcePort(nSourcePort);
			delete nSourcePort;
			break;
		}
		case TAG_SOURCE_SUBADDRESS:{
			if(nMessageSubmissionRequestTLVs.getSourceSubaddress()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceSubaddress *nSourceSubaddress = new SourceSubaddress(buff);
			nSourceSubaddress->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSourceSubaddress(
				nSourceSubaddress);
			delete nSourceSubaddress;
			break;
		}
		case TAG_SOURCE_TELEMATICS_ID:{
			if(nMessageSubmissionRequestTLVs.getSourceTelematicsId()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			SourceTelematicsId *nSourceTelematicsId = 
				new SourceTelematicsId(buff);
			nSourceTelematicsId->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setSourceTelematicsId(
				nSourceTelematicsId);
			delete nSourceTelematicsId;
			break;
		}
		case TAG_USER_MESSAGE_REFERENCE:{
			if(nMessageSubmissionRequestTLVs.getUserMessageReference()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint16 buff;
			if(!_quint16(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UserMessageReference *nUserMessageReference = 
				new UserMessageReference(buff);
			nUserMessageReference->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setUserMessageReference(
				nUserMessageReference);
			delete nUserMessageReference;
			break;
		}
		case TAG_USER_RESPONSE_CODE:{
			if(nMessageSubmissionRequestTLVs.getUserResponseCode()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UserResponseCode *nUserResponseCode = 
				new UserResponseCode(buff);
			nUserResponseCode->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setUserResponseCode(
				nUserResponseCode);
			delete nUserResponseCode;
			break;
		}
		case TAG_USSD_SERVICE_OP:{
			if(nMessageSubmissionRequestTLVs.getUssdServiceOp()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			UssdServiceOp *nUssdServiceOp = new UssdServiceOp(buff);
			nUssdServiceOp->setLength(nTLV.getLength());
			nMessageSubmissionRequestTLVs.setUssdServiceOp(nUssdServiceOp);
			delete nUssdServiceOp;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_MessageSubmissionResponseTLVs(const TLV &nTLV,
	MessageSubmissionResponseTLVs &nMessageSubmissionResponseTLVs) 
	{
	switch(nTLV.getTag()){
		case TAG_ADDITIONAL_STATUS_INFO_TEXT:{
			if(nMessageSubmissionResponseTLVs.getAdditionalStatusInfoText()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			CoctetString buff;
			if(!_CoctetString(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			AdditionalStatusInfoText *nAdditionalStatusInfoText = 
				new AdditionalStatusInfoText(buff);
			nAdditionalStatusInfoText->setLength(nTLV.getLength());
			nMessageSubmissionResponseTLVs.setAdditionalStatusInfoText(
				nAdditionalStatusInfoText);
			delete nAdditionalStatusInfoText;
			break;
		}
		case TAG_DELIVERY_FAILURE_REASON:{
			if(nMessageSubmissionResponseTLVs.getDeliveryFailureReason()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DeliveryFailureReason *nDeliveryFailureReason = 
				new DeliveryFailureReason(buff);
			nDeliveryFailureReason->setLength(nTLV.getLength());
			nMessageSubmissionResponseTLVs.setDeliveryFailureReason(
				nDeliveryFailureReason);
			delete nDeliveryFailureReason;
			break;
		}
		case TAG_DPF_RESULT:{
			if(nMessageSubmissionResponseTLVs.getDpfResult()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			DpfResult *nDpfResult = new DpfResult(buff);
			nDpfResult->setLength(nTLV.getLength());
			nMessageSubmissionResponseTLVs.setDpfResult(nDpfResult);
			delete nDpfResult;
			break;
		}
		case TAG_NETWORK_ERROR_CODE:{
			if(nMessageSubmissionResponseTLVs.getNetworkErrorCode()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			octetString buff;
			if(!_octetString(buff,nTLV.getLength())) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			NetworkErrorCode *nNetworkErrorCode = 
				new NetworkErrorCode(buff);
			nNetworkErrorCode->setLength(nTLV.getLength());
			nMessageSubmissionResponseTLVs.setNetworkErrorCode(
				nNetworkErrorCode);
			delete nNetworkErrorCode;
			break;
		}case TAG_CONGESTION_STATE:{
			if(nMessageSubmissionResponseTLVs.getCongestionState()){
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
			quint8 buff;
			if(!_quint8(buff)) {
				_LastError = ESME_RINVTLVVAL;
				return false;
			}
			CongestionState *nCongestionState = new CongestionState(buff);
			nCongestionState->setLength(nTLV.getLength());
			nMessageSubmissionResponseTLVs.setCongestionState(
				nCongestionState);
			delete nCongestionState;
			break;
		}
		default:{
			_LastError = ESME_RTLVNOTALLWD;
			return false;
		}
	}
	return true;
}

bool Decoder::_DestAddress(DestAddress &nDestAddress){
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVDESTFLAG;
		return false;
	}
	switch(quint8Buff){
		case 0x01:{
			if(!_quint8(quint8Buff)){
				_LastError = ESME_RINVDSTTON;
				return false;
			}
			quint8 quint8Buff1;
			if(!_quint8(quint8Buff1)){
				_LastError = ESME_RINVDSTNPI;
				return false;
			}
			CoctetString CoctetStringBuff;
			if(!_CoctetString(CoctetStringBuff)){
				_LastError = ESME_RINVDSTADR;
				return false;
			}
			nDestAddress.setAddress(quint8Buff,quint8Buff1,CoctetStringBuff);
			break;
		}
		case 0x02:{
			CoctetString CoctetStringBuff;
			if(!_CoctetString(CoctetStringBuff)){
				_LastError = ESME_RINVDLNAME;
				return false;
			}
			nDestAddress.setDistrListName(CoctetStringBuff);
			break;
		}
		default:{
			_LastError = ESME_RINVDESTFLAG;
			return false;
		}		
	}
	return true;
}

bool Decoder::_UnsuccessSME(UnsuccessSME &nUnsuccessSME){
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVDSTTON;
		return false;
	}
	nUnsuccessSME.setDestAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVDSTNPI;
		return false;
	}
	nUnsuccessSME.setDestAddrNPI(quint8Buff);
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVDSTADR;
		return false;
	}
	nUnsuccessSME.setDestinationAddr(CoctetStringBuff);
	quint32 quint32Buff;
	if(!_quint32(quint32Buff)){
		_LastError = ESME_ERRDECERRSTCODE;
		return false;
	}
	nUnsuccessSME.setErrorStatusCode(quint32Buff);
	return true;
}

bool Decoder::_BindBody(Bind &nBind){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RBINDFAIL;
		return false;
	}
	nBind.setSystemId(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RBINDFAIL;
		return false;
	}
	nBind.setPassword(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RBINDFAIL;
		return false;
	}
	nBind.setSystemType(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RBINDFAIL;
		return false;
	}
	nBind.setInterfaceVersion(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RBINDFAIL;
		return false;
	}
	nBind.setAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RBINDFAIL;
		return false;
	}
	nBind.setAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RBINDFAIL;
		return false;
	}
	nBind.setAddressRange(CoctetStringBuff);
	return true;
}

bool Decoder::_BindRespBody(BindResp &nBindResp){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;
		return false;
	}
	nBindResp.setSystemId(CoctetStringBuff);

	while(_Possition<_MaxPossition){
		nBindResp.setScInterfaceVersion(0);
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		switch(nTLV.getTag()){
			case TAG_SC_INTERFACE_VERSION: {
				if(nBindResp.getSrInterfaceVersion()) {
					_LastError = ESME_RTLVNOTALLWD;
					return false;
				}
				quint8 buff;
				if(!_quint8(buff)) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				SrInterfaceVersion *nScInterfaceVersion = 
					new SrInterfaceVersion(buff);
				nScInterfaceVersion->setLength(nTLV.getLength());
				nBindResp.setScInterfaceVersion(nScInterfaceVersion);
				delete nScInterfaceVersion;
				break;
			}
			default: {
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
		}
	}
	return true;
}

bool Decoder::_OutbindBody(Outbind &nOutbind){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;
		return false;
	}
	nOutbind.setSystemId(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVPASWD;
		return false;
	}
	nOutbind.setPassword(CoctetStringBuff);
	return true;
}

bool Decoder::_AlertNotificationBody(AlertNotification &nAlertNotification){
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;
		return false;
	}
	nAlertNotification.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCNPI;
		return false;
	}
	nAlertNotification.setSourceAddrNPI(quint8Buff);
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSRCADR;
		return false;
	}
	nAlertNotification.setSourceAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVDSTTON;
		return false;
	}
	nAlertNotification.setESMEAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVDSTNPI;
		return false;
	}
	nAlertNotification.setESMEAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVDSTADR;
		return false;
	}
	nAlertNotification.setESMEAddr(CoctetStringBuff);
	while(_Possition<_MaxPossition){
		nAlertNotification.setMsAvailabilityStatus(0);
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		switch(nTLV.getTag()){
			case TAG_SC_INTERFACE_VERSION:{
				if(nAlertNotification.getMsAvailabilityStatus()) {
					_LastError = ESME_RTLVNOTALLWD;
					return false;
				}
				quint8 buff;
				if(!_quint8(buff)) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				MsAvailabilityStatus *nMsAvailabilityStatus = 
					new MsAvailabilityStatus(buff);
				nMsAvailabilityStatus->setLength(nTLV.getLength());
				nAlertNotification.setMsAvailabilityStatus(
					nMsAvailabilityStatus);
				delete nMsAvailabilityStatus;
				break;
			}
			default: {
				_LastError = ESME_RTLVNOTALLWD;
				return false;
			}
		}
	}
	return true;
}

bool Decoder::_SubmitSMBody(SubmitSM &nSubmitSM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitSM.setServiceType(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;
		return false;
	}
	nSubmitSM.setSourceAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setDestAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setDestAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitSM.setDestAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setEsmClass(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setProtocolId(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setPriorityFlag(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitSM.setScheduleDeliveryTime(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitSM.setValidityPeriod(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setRegisteredDelivery(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setReplaceIfPresentFlag(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setDataCoding(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setSMDefaultMsgId(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitSM.setSMLength(quint8Buff);
	octetString octetStringBuff;
	if(!_octetString(octetStringBuff,nSubmitSM.getSMLength())){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitSM.setShortMessage(octetStringBuff);

	nSubmitSM.setAlertOnMessageDelivery(0);
	nSubmitSM.setBillingIdentification(0);
	nSubmitSM.setCallbackNum(0);
	nSubmitSM.setCallbackNumAtag(0);
	nSubmitSM.setCallbackNumPresInd(0);
	nSubmitSM.setDestAddrNpCountry(0);
	nSubmitSM.setDestAddrNpInformation(0);
	nSubmitSM.setDestAddrNpResolution(0);
	nSubmitSM.setDestAddrSubunit(0);
	nSubmitSM.setDestBearerType(0);
	nSubmitSM.setDestNetworkId(0);
	nSubmitSM.setDestNetworkType(0);
	nSubmitSM.setDestNodeId(0);
	nSubmitSM.setDestSubaddress(0);
	nSubmitSM.setDestTelematicsId(0);
	nSubmitSM.setDestPort(0);
	nSubmitSM.setDisplayTime(0);
	nSubmitSM.setItsReplyType(0);
	nSubmitSM.setItsSessionInfo(0);
	nSubmitSM.setLanguageIndicator(0);
	nSubmitSM.setMessagePayload(0);
	nSubmitSM.setMoreMessagesToSend(0);
	nSubmitSM.setMsMsgWaitFacilities(0);
	nSubmitSM.setMsValidity(0);
	nSubmitSM.setNumberOfMessages(0);
	nSubmitSM.setPayloadType(0);
	nSubmitSM.setPrivacyIndicator(0);
	nSubmitSM.setQosTimeToLive(0);
	nSubmitSM.setSarMsgRefNum(0);
	nSubmitSM.setSarSegmentSeqnum(0);
	nSubmitSM.setSarTotalSegments(0);
	nSubmitSM.setSetDpf(0);
	nSubmitSM.setSmsSignal(0);
	nSubmitSM.setSourceAddrSubunit(0);
	nSubmitSM.setSourceBearerType(0);
	nSubmitSM.setSourceNetworkId(0);
	nSubmitSM.setSourceNetworkType(0);
	nSubmitSM.setSourceNodeId(0);
	nSubmitSM.setSourcePort(0);
	nSubmitSM.setSourceSubaddress(0);
	nSubmitSM.setSourceTelematicsId(0);
	nSubmitSM.setUserMessageReference(0);
	nSubmitSM.setUserResponseCode(0);
	nSubmitSM.setUssdServiceOp(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_MessageSubmissionRequestTLVs(nTLV,nSubmitSM))
			return false;
	}
	return true;
}

bool Decoder::_SubmitSMRespBody(SubmitSMResp &nSubmitSMResp){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitSMResp.setMessageId(CoctetStringBuff);
	nSubmitSMResp.setAdditionalStatusInfoText(0);
	nSubmitSMResp.setDeliveryFailureReason(0);
	nSubmitSMResp.setDpfResult(0);
	nSubmitSMResp.setNetworkErrorCode(0);
	nSubmitSMResp.setCongestionState(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_MessageSubmissionResponseTLVs(nTLV,nSubmitSMResp))
			return false;
	}
	return true;
}

bool Decoder::_DataSMBody(DataSM &nDataSM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDataSM.setServiceType(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDataSM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDataSM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDataSM.setSourceAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDataSM.setDestAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDataSM.setDestAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDataSM.setDestAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDataSM.setEsmClass(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDataSM.setRegisteredDelivery(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDataSM.setDataCoding(quint8Buff);

	nDataSM.setAlertOnMessageDelivery(0);
	nDataSM.setBillingIdentification(0);
	nDataSM.setCallbackNum(0);
	nDataSM.setCallbackNumAtag(0);
	nDataSM.setCallbackNumPresInd(0);
	nDataSM.setDestAddrNpCountry(0);
	nDataSM.setDestAddrNpInformation(0);
	nDataSM.setDestAddrNpResolution(0);
	nDataSM.setDestAddrSubunit(0);
	nDataSM.setDestBearerType(0);
	nDataSM.setDestNetworkId(0);
	nDataSM.setDestNetworkType(0);
	nDataSM.setDestNodeId(0);
	nDataSM.setDestSubaddress(0);
	nDataSM.setDestTelematicsId(0);
	nDataSM.setDestPort(0);
	nDataSM.setDisplayTime(0);
	nDataSM.setItsReplyType(0);
	nDataSM.setItsSessionInfo(0);
	nDataSM.setLanguageIndicator(0);
	nDataSM.setMessagePayload(0);
	nDataSM.setMoreMessagesToSend(0);
	nDataSM.setMsMsgWaitFacilities(0);
	nDataSM.setMsValidity(0);
	nDataSM.setNumberOfMessages(0);
	nDataSM.setPayloadType(0);
	nDataSM.setPrivacyIndicator(0);
	nDataSM.setQosTimeToLive(0);
	nDataSM.setSarMsgRefNum(0);
	nDataSM.setSarSegmentSeqnum(0);
	nDataSM.setSarTotalSegments(0);
	nDataSM.setSetDpf(0);
	nDataSM.setSmsSignal(0);
	nDataSM.setSourceAddrSubunit(0);
	nDataSM.setSourceBearerType(0);
	nDataSM.setSourceNetworkId(0);
	nDataSM.setSourceNetworkType(0);
	nDataSM.setSourceNodeId(0);
	nDataSM.setSourcePort(0);
	nDataSM.setSourceSubaddress(0);
	nDataSM.setSourceTelematicsId(0);
	nDataSM.setUserMessageReference(0);
	nDataSM.setUserResponseCode(0);
	nDataSM.setUssdServiceOp(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_MessageSubmissionRequestTLVs(nTLV,nDataSM))
			return false;
	}
	return true;
}

bool Decoder::_DataSMRespBody(DataSMResp &nDataSMResp){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDataSMResp.setMessageId(CoctetStringBuff);

	nDataSMResp.setAdditionalStatusInfoText(0);
	nDataSMResp.setDeliveryFailureReason(0);
	nDataSMResp.setDpfResult(0);
	nDataSMResp.setNetworkErrorCode(0);
	nDataSMResp.setCongestionState(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_MessageSubmissionResponseTLVs(nTLV,nDataSMResp))
			return false;
	}
	return true;
}

bool Decoder::_SubmitMultiBody(SubmitMulti &nSubmitMulti){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitMulti.setServiceType(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitMulti.setSourceAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setNumberOfDest(quint8Buff);

	QVector<DestAddress> nDestAddresses;
	quint8 size(nSubmitMulti.getNumberOfDest());
	if(size>0){
		nDestAddresses.resize(size);
		for(quint8 i=0;i<size;i++){
			DestAddress nDestAddress;
			if(!_DestAddress(nDestAddress))
				return false;
			nDestAddresses[i] = nDestAddress;
		}
		nSubmitMulti.setDestAddress(nDestAddresses);
	}else
		nSubmitMulti.setDestAddress(nDestAddresses);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setEsmClass(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setProtocolId(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setPriorityFlag(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitMulti.setScheduleDeliveryTime(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitMulti.setValidityPeriod(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setRegisteredDelivery(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setReplaceIfPresentFlag(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setDataCoding(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setSMDefaultMsgId(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMulti.setSMLength(quint8Buff);
	octetString octetStringBuff;
	if(!_octetString(octetStringBuff,nSubmitMulti.getSMLength())){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitMulti.setShortMessage(octetStringBuff);
	nSubmitMulti.setAlertOnMessageDelivery(0);
	nSubmitMulti.setBillingIdentification(0);
	nSubmitMulti.setCallbackNum(0);
	nSubmitMulti.setCallbackNumAtag(0);
	nSubmitMulti.setCallbackNumPresInd(0);
	nSubmitMulti.setDestAddrNpCountry(0);
	nSubmitMulti.setDestAddrNpInformation(0);
	nSubmitMulti.setDestAddrNpResolution(0);
	nSubmitMulti.setDestAddrSubunit(0);
	nSubmitMulti.setDestBearerType(0);
	nSubmitMulti.setDestNetworkId(0);
	nSubmitMulti.setDestNetworkType(0);
	nSubmitMulti.setDestNodeId(0);
	nSubmitMulti.setDestSubaddress(0);
	nSubmitMulti.setDestTelematicsId(0);
	nSubmitMulti.setDestPort(0);
	nSubmitMulti.setDisplayTime(0);
	nSubmitMulti.setItsReplyType(0);
	nSubmitMulti.setItsSessionInfo(0);
	nSubmitMulti.setLanguageIndicator(0);
	nSubmitMulti.setMessagePayload(0);
	nSubmitMulti.setMoreMessagesToSend(0);
	nSubmitMulti.setMsMsgWaitFacilities(0);
	nSubmitMulti.setMsValidity(0);
	nSubmitMulti.setNumberOfMessages(0);
	nSubmitMulti.setPayloadType(0);
	nSubmitMulti.setPrivacyIndicator(0);
	nSubmitMulti.setQosTimeToLive(0);
	nSubmitMulti.setSarMsgRefNum(0);
	nSubmitMulti.setSarSegmentSeqnum(0);
	nSubmitMulti.setSarTotalSegments(0);
	nSubmitMulti.setSetDpf(0);
	nSubmitMulti.setSmsSignal(0);
	nSubmitMulti.setSourceAddrSubunit(0);
	nSubmitMulti.setSourceBearerType(0);
	nSubmitMulti.setSourceNetworkId(0);
	nSubmitMulti.setSourceNetworkType(0);
	nSubmitMulti.setSourceNodeId(0);
	nSubmitMulti.setSourcePort(0);
	nSubmitMulti.setSourceSubaddress(0);
	nSubmitMulti.setSourceTelematicsId(0);
	nSubmitMulti.setUserMessageReference(0);
	nSubmitMulti.setUserResponseCode(0);
	nSubmitMulti.setUssdServiceOp(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_MessageSubmissionRequestTLVs(nTLV,nSubmitMulti))
			return false;
	}
	return true;
}

bool Decoder::_SubmitMultiRespBody(SubmitMultiResp &nSubmitMultiResp){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nSubmitMultiResp.setMessageId(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nSubmitMultiResp.setNoUnsuccess(quint8Buff);

	QVector<UnsuccessSME> nUnsuccessSMEes;
	quint8 size(nSubmitMultiResp.getNoUnsuccess());
	if(size>0){
		nUnsuccessSMEes.resize(size);
		for(quint8 i=0;i<size;i++){
			UnsuccessSME nUnsuccessSME;
			if(!_UnsuccessSME(nUnsuccessSME))
				return false;
			nUnsuccessSMEes[i] = nUnsuccessSME;
		}
		nSubmitMultiResp.setUnsuccessSME(nUnsuccessSMEes);
	}else
		nSubmitMultiResp.setUnsuccessSME(nUnsuccessSMEes);
	return true;
}

bool Decoder::_DeliverSMBody(DeliverSM &nDeliverSM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDeliverSM.setServiceType(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDeliverSM.setSourceAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setDestAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setDestAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDeliverSM.setDestAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setEsmClass(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setProtocolId(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setPriorityFlag(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDeliverSM.setScheduleDeliveryTime(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDeliverSM.setValidityPeriod(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setRegisteredDelivery(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setReplaceIfPresentFlag(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setDataCoding(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setSMDefaultMsgId(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nDeliverSM.setSMLength(quint8Buff);
	octetString octetStringBuff;
	if(!_octetString(octetStringBuff,nDeliverSM.getSMLength())){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDeliverSM.setShortMessage(octetStringBuff);

	nDeliverSM.setCallbackNum(0);
	nDeliverSM.setCallbackNumAtag(0);
	nDeliverSM.setCallbackNumPresInd(0);
	nDeliverSM.setDestAddrNpCountry(0);
	nDeliverSM.setDestAddrNpInformation(0);
	nDeliverSM.setDestAddrNpResolution(0);
	nDeliverSM.setDestAddrSubunit(0);
	nDeliverSM.setDestNetworkId(0);
	nDeliverSM.setDestNodeId(0);
	nDeliverSM.setDestSubaddress(0);
	nDeliverSM.setDestPort(0);
	nDeliverSM.setDpfResult(0);
	nDeliverSM.setItsReplyType(0);
	nDeliverSM.setItsSessionInfo(0);
	nDeliverSM.setLanguageIndicator(0);
	nDeliverSM.setMessagePayload(0);
	nDeliverSM.setMessageState(0);
	nDeliverSM.setNetworkErrorCode(0);
	nDeliverSM.setPayloadType(0);
	nDeliverSM.setPrivacyIndicator(0);
	nDeliverSM.setReceiptedMessageId(0);
	nDeliverSM.setSarMsgRefNum(0);
	nDeliverSM.setSarSegmentSeqnum(0);
	nDeliverSM.setSarTotalSegments(0);
	nDeliverSM.setSourceAddrSubunit(0);
	nDeliverSM.setSourceNetworkId(0);
	nDeliverSM.setSourceNodeId(0);
	nDeliverSM.setSourcePort(0);
	nDeliverSM.setSourceSubaddress(0);
	nDeliverSM.setUserMessageReference(0);
	nDeliverSM.setUserResponseCode(0);
	nDeliverSM.setUssdServiceOp(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_MessageDeliveryRequestTLVs(nTLV,nDeliverSM))
			return false;
	}
	return true;
}

bool Decoder::_DeliverSMRespBody(DeliverSMResp &nDeliverSMResp){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nDeliverSMResp.setMessageId(CoctetStringBuff);

	nDeliverSMResp.setAdditionalStatusInfoText(0);
	nDeliverSMResp.setDeliveryFailureReason(0);
	nDeliverSMResp.setNetworkErrorCode(0);
	while(_Possition!=_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_MessageDeliveryResponseTLVs(nTLV,nDeliverSMResp))
			return false;
	}
	return true;
}

bool Decoder::_BroadcastSMBody(BroadcastSM &nBroadcastSM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nBroadcastSM.setServiceType(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nBroadcastSM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nBroadcastSM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nBroadcastSM.setSourceAddr(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nBroadcastSM.setMessageId(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nBroadcastSM.setPriorityFlag(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nBroadcastSM.setScheduleDeliveryTime(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nBroadcastSM.setValidityPeriod(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nBroadcastSM.setReplaceIfPresentFlag(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nBroadcastSM.setDataCoding(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSRCTON;//TODO
		return false;
	}
	nBroadcastSM.setSMDefaultMsgId(quint8Buff);

	nBroadcastSM.setBroadcastAreaIdentifier(0);
	nBroadcastSM.setBroadcastContentType(0);
	nBroadcastSM.setBroadcastRepNum(0);
	nBroadcastSM.setBroadcastFrequencyInterval(0);
	nBroadcastSM.setAlertOnMessageDelivery(0);
	nBroadcastSM.setBroadcastChannelIndicator(0);
	nBroadcastSM.setBroadcastContentTypeInfo(0);
	nBroadcastSM.setBroadcastMessageClass(0);
	nBroadcastSM.setBroadcastServiceGroup(0);
	nBroadcastSM.setCallbackNum(0);
	nBroadcastSM.setCallbackNumAtag(0);
	nBroadcastSM.setCallbackNumPresInd(0);
	nBroadcastSM.setDestAddrSubunit(0);
	nBroadcastSM.setDestSubaddress(0);
	nBroadcastSM.setDestPort(0);
	nBroadcastSM.setDisplayTime(0);
	nBroadcastSM.setLanguageIndicator(0);
	nBroadcastSM.setMessagePayload(0);
	nBroadcastSM.setMsValidity(0);
	nBroadcastSM.setPayloadType(0);
	nBroadcastSM.setPrivacyIndicator(0);
	nBroadcastSM.setSmsSignal(0);
	nBroadcastSM.setSourceAddrSubunit(0);
	nBroadcastSM.setSourcePort(0);
	nBroadcastSM.setSourceSubaddress(0);
	nBroadcastSM.setUserMessageReference(0);
	nBroadcastSM.setBroadcastErrorStatus(0);
	nBroadcastSM.setFailedBroadcastAreaIdentifier(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		switch(nTLV.getTag()){
			case TAG_BROADCAST_AREA_IDENTIFIER:{
				if(nBroadcastSM.getBroadcastAreaIdentifier()) {
					_LastError = ESME_RTLVNOTALLWD;
					return false;
				}
				octetString buff;
				if(!_octetString(buff,nTLV.getLength())) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				BroadcastAreaIdentifier *nBroadcastAreaIdentifier = 
					new BroadcastAreaIdentifier(buff);
				nBroadcastAreaIdentifier->setLength(nTLV.getLength());
				nBroadcastSM.setBroadcastAreaIdentifier(
					nBroadcastAreaIdentifier);
				delete nBroadcastAreaIdentifier;
				break;
			}
			case TAG_BROADCAST_CONTENT_TYPE:{
				if(nBroadcastSM.getBroadcastContentType()) {
					_LastError = ESME_RTLVNOTALLWD;
					return false;
				}
				octetString buff;
				if(!_octetString(buff,nTLV.getLength())) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				BroadcastContentType *nBroadcastContentType = 
					new BroadcastContentType(buff);
				nBroadcastContentType->setLength(nTLV.getLength());
				nBroadcastSM.setBroadcastContentType(
					nBroadcastContentType);
				delete nBroadcastContentType;
				break;
			}
			case TAG_BROADCAST_REP_NUM:{
				if(nBroadcastSM.getBroadcastRepNum()) {
					_LastError = ESME_RTLVNOTALLWD;
					return false;
				}
				quint16 buff;
				if(!_quint16(buff)) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				BroadcastRepNum *nBroadcastRepNum = 
					new BroadcastRepNum(buff);
				nBroadcastRepNum->setLength(nTLV.getLength());
				nBroadcastSM.setBroadcastRepNum(nBroadcastRepNum);
				delete nBroadcastRepNum;
				break;
			}
			case TAG_BROADCAST_FREQUENCY_INTERVAL:{
				if(nBroadcastSM.getBroadcastFrequencyInterval()) {
					_LastError = ESME_RTLVNOTALLWD;
					return false;
				}
				octetString buff;
				if(!_octetString(buff,nTLV.getLength())) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				BroadcastFrequencyInterval *nBroadcastFrequencyInterval = 
					new BroadcastFrequencyInterval(buff);
				nBroadcastFrequencyInterval->setLength(nTLV.getLength());
				nBroadcastSM.setBroadcastFrequencyInterval(
					nBroadcastFrequencyInterval);
				delete nBroadcastFrequencyInterval;
				break;
			}
			default:{
				if(!_BroadcastRequestOptionalTLVs(nTLV,nBroadcastSM))
					return false;
				break;
			}
		}
	}
	return true;
}

bool Decoder::_BroadcastSMRespBody(BroadcastSMResp &nBroadcastSMResp){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nBroadcastSMResp.setMessageId(CoctetStringBuff);

	nBroadcastSMResp.setBroadcastErrorStatus(0);
	nBroadcastSMResp.setFailedBroadcastAreaIdentifier(0);
	while(_Possition!=_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_BroadcastResponseOptionalTLVs(nTLV,nBroadcastSMResp))
			return false;
	}
	return true;
}

bool Decoder::_CancelSMBody(CancelSM &nCancelSM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelSM.setServiceType(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelSM.setMessageId(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelSM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelSM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelSM.setSourceAddr(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelSM.setDestAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelSM.setDestAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelSM.setDestAddr(CoctetStringBuff);
	return true;
}

bool Decoder::_QuerySMBody(QuerySM &nQuerySM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQuerySM.setMessageId(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQuerySM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQuerySM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQuerySM.setSourceAddr(CoctetStringBuff);
	return true;
}

bool Decoder::_QuerySMRespBody(QuerySMResp &nQuerySMResp){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQuerySMResp.setMessageId(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQuerySMResp.setFinalDate(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQuerySMResp.setMessageState(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQuerySMResp.setErrorCode(quint8Buff);
	return true;
}

bool Decoder::_ReplaceSMBody(ReplaceSM &nReplaceSM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setMessageId(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setSourceAddr(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setScheduleDeliveryTime(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setValidityPeriod(CoctetStringBuff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setRegisteredDelivery(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setSMDefaultMsgId(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setSMLength(quint8Buff);
	octetString octetStringBuff;
	if(!_octetString(octetStringBuff,nReplaceSM.getSMLength())){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nReplaceSM.setShortMessage(octetStringBuff);

	nReplaceSM.setMessagePayload(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_MessageReplacementTLVs(nTLV,nReplaceSM))
			return false;
	}
	return true;
}

bool Decoder::_QueryBroadcastSMBody(QueryBroadcastSM &nQueryBroadcastSM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQueryBroadcastSM.setMessageId(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQueryBroadcastSM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQueryBroadcastSM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQueryBroadcastSM.setSourceAddr(CoctetStringBuff);
	nQueryBroadcastSM.setUserMessageReference(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_QueryBroadcastRequestOptionalTLVs(nTLV,nQueryBroadcastSM))
			return false;
	}
	return true;
}

bool Decoder::_QueryBroadcastSMRespBody(
	QueryBroadcastSMResp &nQueryBroadcastSMResp){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nQueryBroadcastSMResp.setMessageId(CoctetStringBuff);

	nQueryBroadcastSMResp.setMessageState(0);
	nQueryBroadcastSMResp.setBroadcastAreaSuccess(0);
	QVector<BroadcastAreaIdentifier> nBroadcastAreaIdentifier;
	nQueryBroadcastSMResp.setBroadcastEndTime(0);
	nQueryBroadcastSMResp.setUserMessageReference(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		switch(nTLV.getTag()){
			case TAG_MESSAGE_STATE:{
				if(nQueryBroadcastSMResp.getMessageState()) {
					_LastError = ESME_RTLVNOTALLWD;
					return false;
				}
				quint8 buff;
				if(!_quint8(buff)) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				MessageState *nMessageState = new MessageState(buff);
				nMessageState->setLength(nTLV.getLength());
				nQueryBroadcastSMResp.setMessageState(nMessageState);
				delete nMessageState;
				break;
			}
			case TAG_BROADCAST_AREA_SUCCESS:{
				if(nQueryBroadcastSMResp.getBroadcastAreaSuccess()) {
					_LastError = ESME_RTLVNOTALLWD;
					return false;
				}
				quint8 buff;
				if(!_quint8(buff)) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				BroadcastAreaSuccess *nBroadcastAreaSuccess = 
					new BroadcastAreaSuccess(buff);
				nBroadcastAreaSuccess->setLength(nTLV.getLength());
				nQueryBroadcastSMResp.setBroadcastAreaSuccess(
					nBroadcastAreaSuccess);
				delete nBroadcastAreaSuccess;
				break;
			}
			case TAG_BROADCAST_AREA_IDENTIFIER:{
				octetString buff;
				if(!_octetString(buff,nTLV.getLength()&0x00FF)) {
					_LastError = ESME_RINVTLVVAL;
					return false;
				}
				BroadcastAreaIdentifier nnBroadcastAreaIdentifier(buff);
				nnBroadcastAreaIdentifier.setLength(nTLV.getLength());
				nBroadcastAreaIdentifier.push_back(
					nnBroadcastAreaIdentifier);
				break;
			}
			default:{
				_QueryBroadcastResponseOptionalTLVs(nTLV,nQueryBroadcastSMResp);
				break;
			}
		}
	}
	nQueryBroadcastSMResp.setBroadcastAreaIdentifier(nBroadcastAreaIdentifier);
	return true;
}

bool Decoder::_CancelBroadcastSMBody(CancelBroadcastSM &nCancelBroadcastSM){
	CoctetString CoctetStringBuff;
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelBroadcastSM.setServiceType(CoctetStringBuff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelBroadcastSM.setMessageId(CoctetStringBuff);
	quint8 quint8Buff;
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelBroadcastSM.setSourceAddrTON(quint8Buff);
	if(!_quint8(quint8Buff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelBroadcastSM.setSourceAddrNPI(quint8Buff);
	if(!_CoctetString(CoctetStringBuff)){
		_LastError = ESME_RINVSYSID;//TODO
		return false;
	}
	nCancelBroadcastSM.setSourceAddr(CoctetStringBuff);

	nCancelBroadcastSM.setBroadcastContentType(0);
	nCancelBroadcastSM.setUserMessageReference(0);
	while(_Possition<_MaxPossition){
		TLV nTLV;
		if(!_TLVbase(nTLV))
			return false;
		if(!_CancelBroadcastOptionalTLVs(nTLV,nCancelBroadcastSM))
			return false;
	}
	return true;
}
